﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ArtOfTest.WebAii.Controls.HtmlControls;
using ArtOfTest.WebAii.Core;
using ArtOfTest.WebAii.ObjectModel;

namespace Adapter.SISCONVE.Pages
{
    public class BasePage
    {

        #region Constants

        protected const int DEFAULT_TIMEOUT = 700000000;
        protected const int DEFAULT_ATTRIBUTES_TIMEOUT = 600000;

        public Manager manager;

        #endregion

        #region Constructors

        public BasePage(Manager manager)
        {
            this.manager = manager;
        }

        public BasePage()
        { }

        #endregion

        #region operation: actions


        /// <summary>
        /// Gets the current instance of the browser
        /// </summary>
        /// <returns>The browser</returns>
        public Browser GetBrowser()
        {
            if (manager != null)
                return manager.ActiveBrowser;
            return null;
        }

        /// <summary>
        /// Gets a web element providing a specific timeout.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        /// <param name="timeout">Time to wait for the element</param>
        /// <returns></returns>
        public Element GetElement(String locator, int timeout)
        {
            return GetBrowser().WaitForElement(new HtmlFindExpression(locator), timeout, false);
        }

        /// <summary>
        /// Gets a web element.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        /// <returns></returns>
        public Element GetElement(String locator)
        {
            return GetElement(locator, DEFAULT_TIMEOUT);
        }

        /// <summary>
        /// Waits for existance of a web element.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        /// <returns></returns>
        public void WaitForElement(String locator)
        {
            GetElement(locator, DEFAULT_TIMEOUT);
        }

        /// <summary>
        /// Click on an element providing a specific timeout.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        /// <param name="timeout">Time to wait for the element</param>
        public void Click(String locator, int timeout)
        {
            Element element = GetElement(locator, timeout);
            GetBrowser().Actions.Click(element);
        }

        /// <summary>
        /// Click on an element.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        public void Click(String locator)
        {
            AfterNavigation();
            Element element = GetElement(locator, DEFAULT_TIMEOUT);
            GetBrowser().Actions.Click(element);
        }

        /// <summary>
        /// Gets the text of an element.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        /// <returns></returns>
        public String GetText(String locator)
        {
            Element element = GetElement(locator);
            return element.GetTextContentRecursive();
        }

        /// <summary>
        /// Write a text in the specified locator.
        /// </summary>
        /// <param name="locator">The locator of the element</param>
        /// <param name="text">The text to write</param>
        public void SetText(String locator, String text)
        {
            Element element = GetElement(locator, DEFAULT_TIMEOUT);
            GetBrowser().Actions.SetText(element, text);
            AfterNavigation();
        }

        /// <summary>
        /// Gets the text displayed when the mouse is over an element. It gets the title of the span.
        /// </summary>
        /// <param name="locator">The title of the element</param>
        /// <returns></returns>
        public String GetElementTitle(String locator)
        {
            Element element = GetElement(locator);
            return element.GetAttributeValueOrEmpty("title");
        }

        public void AfterNavigation()
        {
            GetBrowser().WaitUntilReady();
            GetBrowser().WaitForAjax(DEFAULT_TIMEOUT);
            GetBrowser().RefreshDomTree();
        }

        public String ContainingClass(String className)
        {
            return "contains(concat(' ',normalize-space(@class),' '),' " + className + " ')";
        }

        /// Verifies if an element is visible in the current page
        /// </summary>
        /// <param name="element">the element to be checked</param>
        /// <returns>TRUE if the element is visible</returns>
        public bool IsVisible(Element element)
        {
            HtmlContainerControl control = new HtmlContainerControl(element);
            bool visible = false;

            bool visibility = false;
            bool isInherit = false;
            String visibilityValue = control.GetComputedStyleValue("visibility");
            if (("visible").Equals(visibilityValue))
                visibility = true;
            if (("inherit").Equals(visibilityValue))
                isInherit = true;

            String displayValue = control.GetComputedStyleValue("display");
            if (("block").Equals(displayValue) || ("inline").Equals(displayValue) || ("inline-block").Equals(displayValue) || ("table-cell").Equals(displayValue))
                visible = true;

            if (isInherit)
                return visible;
            else
                return visible && visibility;
        }

        #endregion

        # region helpers

        public virtual void WaitUntilPageReady()
        {
            GetBrowser().WaitUntilReady();
            GetBrowser().WaitForAjax(DEFAULT_TIMEOUT);
        }

        

        # endregion
    }
}
